
package com.platform.modules.app.controller;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.code.kaptcha.Producer;
import com.platform.annotation.LoginUser;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.config.KaptchaConfig;
import com.platform.modules.app.entity.user.UserShopsVo;
import com.platform.modules.bk.entity.BkCustomerEntity;
import com.platform.modules.bk.service.BkCustomerService;
import com.platform.modules.mall.dao.MallCollectDao;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.service.*;
import com.platform.modules.oss.cloud.UploadFactory;
import com.platform.modules.sys.service.SysConfigService;
import io.swagger.annotations.*;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author
 */
@RestController
@RequestMapping("/app/user")
@Api(tags = "AppUserController|APP用户接口")
public class AppUserController extends AppBaseController {
    @Autowired
    private MallUserLevelService userLevelService;
    @Autowired
    private MallFootprintService footprintService;
    @Autowired
    private MallCollectService collectService;
    @Autowired
    private MallFeedbackService feedbackService;
    @Autowired
    private MallAccountLogService accountLogService;
    @Autowired
    private BkCustomerService bkCustomerService;
    @Autowired
    private MallUserService userService;
    @Autowired
    private WxMaQrcodeService maQrcodeService;
    @Autowired
    private MallUserIntegralLogService mallUserIntegralLogService;
    @Autowired
    private MallUserCardService userCardService;
    @Resource
    private JedisUtil jedisUtil;

    @Autowired
    private SysConfigService sysConfigService;


    @RequestMapping("/setUserInfo")
    @ApiOperation(value = "设置用户信息", notes = "设置用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "file", name = "file", value = "头像图片", required = true),
            @ApiImplicitParam(paramType = "name", name = "name", value = "用户名称"),
    })
    public RestResponse setUserInfo(@RequestParam Map<String,Object> params, MultipartFile file){
        params.put("file",file);
        params.put("id",getUserId());
        if(!userService.setUserInfo(params)){
            return RestResponse.error("保存失败，请稍后再试");
        }
        return RestResponse.success();
    }


    @GetMapping("/userIntegralRecord")
    @ApiOperation(value = "获取登录用户信息", notes = "根据token获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "int", name = "page", value = "当前页", example = "1", required = false, dataType = "int"),
            @ApiImplicitParam(paramType = "int", name = "limit", value = "显示数量", example = "10", required = false, dataType = "int"),
            @ApiImplicitParam(paramType = "int", name = "type", value = "变动类型：0消耗，1增加 （不传表示两个都查）", example = "10", required = false, dataType = "int"),
    })
    public RestResponse userIntegralRecord(@RequestParam Map<String, Object> params) {
        params.put("userId", getUserId());
        Page page = mallUserIntegralLogService.queryPage(params);
        return RestResponse.success().put("page", page);
    }

    /**
     * 根据token获取当前登录用户信息
     *
     * @param user user
     * @return RestResponse
     */
    @GetMapping("/userInfo")
    @ApiOperation(value = "获取登录用户信息", notes = "根据token获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
    })
    public RestResponse userInfo(@LoginUser MallUserEntity user) {
//        if (StringUtils.isNotBlank(user.getCustomerNo())) {
//            BkCustomerEntity customerEntity = bkCustomerService.getById(user.getCustomerNo());
//            if (customerEntity != null) {
//                user.setSignAllIntegral(customerEntity.getAvailablePoints().add(user.getSignAllIntegral()));
//            }
//        }
//        return RestResponse.success().put("data", user);

        MallUserLevelEntity levelEntity = userLevelService.getById(user.getUserLevelId());
        if (null != levelEntity) {
            user.setUserLevelName(levelEntity.getName());
        } else {
            user.setUserLevelName("");
        }
        return RestResponse.success().put("data", user);
    }

    /**
     * 查询当前登录用户足迹列表
     *
     * @param user user
     * @return RestResponse
     */
    @GetMapping("/footprintList")
    @ApiOperation(value = "查询当前登录用户足迹列表", notes = "查询当前登录用户足迹列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "current", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int")
    })
    public RestResponse footprintList(@LoginUser MallUserEntity user, @RequestParam(defaultValue = "1") Integer current,
                                      @RequestParam(defaultValue = "10") Integer limit) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", user.getId());
        params.put("page", current);
        params.put("limit", limit);
        IPage data = footprintService.queryPage(params);
        return RestResponse.success().put("data", data);
    }

    /**
     * 删除足迹
     */
    @PostMapping("/deleteFootPrint")
    @ApiOperation(value = "删除足迹", notes = "用户删除足迹")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "body", name = "jsonParam", value = "JSON格式参数", examples = @Example({
                    @ExampleProperty(mediaType = "footprintId", value = "1")
            }), required = true, dataType = "string")
    })
    public RestResponse deleteFootPrint(@LoginUser MallUserEntity loginUser, @RequestBody JSONObject jsonParam) {
        String footprintId = jsonParam.getString("footprintId");
        if (footprintId == null) {
            return RestResponse.error("删除出错");
        }
        MallFootprintEntity footprintEntity = footprintService.getById(footprintId);
        //
        if (loginUser == null || loginUser.getId() == null || footprintEntity == null || footprintEntity.getGoodsId() == null) {
            return RestResponse.error("删除出错");
        }

        Map<String, Object> param = new HashMap<>(4);
        param.put("USER_ID", loginUser.getId());
        param.put("GOODS_ID", footprintEntity.getGoodsId());
        footprintService.removeByMap(param);

        return RestResponse.success("删除成功");
    }

    /**
     * 当前登录用户最近新关注的三家店铺 图片
     *
     * @return RestResponse
     */
    @GetMapping("/colShopsImg")
    @ApiOperation(value = "当前登录用户最近新关注的三家店铺(图片)", notes = "当前登录用户最近新关注的三家店铺(图片)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
    })
    public RestResponse colShopsImg() {
        String userId = getUserId();
        JSONObject reslut = jedisUtil.getCache(Constant.COLLECT_SHOPS_IMAGE + userId, () -> {
            JSONObject result = new JSONObject();
            result.put("image", ((MallCollectDao) collectService.getBaseMapper()).colShopsImg(userId));
            result.put("count", collectService.lambdaQuery().eq(MallCollectEntity::getUserId, userId).eq(MallCollectEntity::getType, 1).count());
            return result;
        }, JSONObject.class);
        return RestResponse.success().put("data", reslut);
    }

    /**
     * 当前登录用户收藏列表
     *
     * @param user user
     * @return RestResponse
     */
    @GetMapping("/collectList")
    @ApiOperation(value = "当前登录用户收藏列表", notes = "当前登录用户收藏列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "longitude", value = "经度", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "latitude", value = "纬度", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "条数", required = true, dataType = "Integer"),
            @ApiImplicitParam(paramType = "query", name = "page", value = "页码", required = true, dataType = "Integer")
    })
    public RestResponse collectList(@LoginUser MallUserEntity user, @ApiIgnore UserShopsVo vo) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", user.getId());
        params.put("longitude", vo.getLongitude());
        params.put("latitude",vo.getLatitude());
        params.put("lim",vo.getLimit());
        params.put("page",(vo.getPage()-1)*vo.getLimit());
        List<MallShopsEntity> footprintEntityList = collectService.queryUserJoinShops(params);
        return RestResponse.success().put("data", footprintEntityList);
    }

    /**
     * 添加或删除用户收藏
     */
    @PostMapping("/addOrDelete")
    @ApiOperation(value = "添加或删除用户收藏", notes = "添加或删除用户收藏")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "body", name = "jsonParam", value = "JSON格式参数", examples = @Example({
                    @ExampleProperty(mediaType = "goodsId", value = "1")
            }), required = true, dataType = "string")
    })
    public RestResponse addOrDelete(@RequestBody MallCollectEntity collectEntity) {
        String userId = getUserId();
        collectEntity.setUserId(userId);
        List<MallCollectEntity> collectEntities = collectService.queryBy(collectEntity);
        boolean collectRes;
        String handleType = "add";
        if (null == collectEntities || collectEntities.size() < 1) {
            collectEntity.setAddTime(new Date());
            collectEntity.setUserId(userId);
            //添加收藏
            collectRes = collectService.save(collectEntity);
        } else {
            //取消收藏
            collectRes = collectService.delete(collectEntities.get(0).getId());
            handleType = "delete";
        }

        if (collectRes) {
            jedisUtil.del(Constant.COLLECT_SHOPS_IMAGE + userId);
            return RestResponse.success().put("data", handleType);
        }
        return RestResponse.error("操作失败");
    }

    /**
     * 添加反馈
     */
    @PostMapping("saveFeedBack")
    @ApiOperation(value = "添加反馈", notes = "用户添加反馈")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "body", name = "jsonParam", value = "JSON格式参数", examples = @Example({
                    @ExampleProperty(mediaType = "mobile", value = ""),
                    @ExampleProperty(mediaType = "feedType", value = "1"),
                    @ExampleProperty(mediaType = "content", value = "反馈的内容")
            }), required = true, dataType = "string")
    })
    public RestResponse saveFeedBack(@LoginUser MallUserEntity loginUser, @RequestBody JSONObject feedbackJson) {
        MallFeedbackEntity feedbackVo = new MallFeedbackEntity();
        feedbackVo.setUserId(loginUser.getId());
        feedbackVo.setMobile(feedbackJson.getString("mobile"));
        feedbackVo.setFeedType(feedbackJson.getInteger("feedType"));
        feedbackVo.setStatus(1);
        feedbackVo.setContent(feedbackJson.getString("content"));
        feedbackVo.setAddTime(new Date());
        feedbackService.save(feedbackVo);
        return RestResponse.success();
    }

    /**
     * 当前登录用户账户余额变动记录
     *
     * @param user user
     * @return RestResponse
     */
    @GetMapping("accountLogList")
    @ApiOperation(value = "当前登录用户收藏列表", notes = "当前登录用户收藏列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
    })
    public RestResponse accountLogList(@LoginUser MallUserEntity user) {
        List<MallAccountLogEntity> accountLogEntityList = accountLogService.list(
                new QueryWrapper<MallAccountLogEntity>().eq("USER_ID", user.getId()).ne("TYPE", 0));
        return RestResponse.success().put("data", accountLogEntityList);
    }

    /**
     * 修改用户信息
     */
    @PostMapping("modifyUserInfo")
    @ApiOperation(value = "修改用户信息", notes = "修改用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", name = "jsonParam", value = "JSON格式参数", examples = @Example({
                    @ExampleProperty(mediaType = "nickname", value = "xx"),
                    @ExampleProperty(mediaType = "avatarUrl", value = "1234"),
            }), required = true, dataType = "string")
    })
    public RestResponse modifyUserInfo(@RequestBody JSONObject jsonParams, @LoginUser MallUserEntity userEntity) {

        String nickname = jsonParams.getString("nickname");
        String avatarUrl = jsonParams.getString("avatarUrl");
        //String unionId = jsonParams.getString("unionId");
        if (StringUtils.isBlank(nickname) && StringUtils.isBlank(avatarUrl)) {
            return RestResponse.error("参数为空");
        }
        if (StringUtils.isBlank(userEntity.getId())) {
            return RestResponse.error("未找到用户");
        }

        userService.update(new LambdaUpdateWrapper<MallUserEntity>().set(MallUserEntity::getNickname, nickname)
                .set(MallUserEntity::getHeadImgUrl, avatarUrl).eq(MallUserEntity::getId, userEntity.getId()));

        return RestResponse.success("成功");
    }

    //createWxaCodeUnlimitBytes


    @Value("${wx.config.envVersion}")
    private String envVersion;

    /**
     * 获取商品小程序码
     *
     * @param user
     * @param width
     * @return
     */
    @GetMapping("/getUserQrCode")
    @ApiOperation(value = "获取商品小程序码", notes = "获取商品小程序码")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "width", value = "小程序码宽度", example = "250", required = true, dataType = "string")
    })
    public RestResponse getUserQrCode(@LoginUser MallUserEntity user, @RequestParam(defaultValue = "250") Integer width) {
        String page = "/pages/wode/login/login?referrer=" + user.getId();
        try {
            String url = user.getQrCode();
            if (StringUtils.isBlank(url)) {
                //byte[] bytes = maQrcodeService.createWxaCodeBytes(page, width, false, new WxMaCodeLineColor("0", "0", "0"), true);
                byte[] bytes = maQrcodeService.createWxaCodeBytes(page,envVersion,width, false, new WxMaCodeLineColor("0", "0", "0"), true);

                url = UploadFactory.build().uploadSuffix(bytes, ".png");
                userService.update(new LambdaUpdateWrapper<MallUserEntity>().set(MallUserEntity::getQrCode, url)
                        .eq(MallUserEntity::getId, user.getId()));
            }

            return RestResponse.success().put("url", url);
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new BusinessException("获取小程序码失败！");
        }
    }

    @PostMapping("/queryUserCard")
    @ApiOperation(value = "查看我的卡券", notes = "查看我的卡券")
    public RestResponse queryUserCard(@LoginUser MallUserEntity user){

        List<MallUserCardEntity> mallUserCardEntities = userCardService.selectUserCard(user.getId());

        return RestResponse.success().put("data",mallUserCardEntities);
    }

    /**
     * 联系我们
     */
    @GetMapping("callCenter")
    @ApiOperation(value = "联系我们", notes = "联系我们")
    @ApiImplicitParams({
    })
    public RestResponse callCenter() {
        String callCenterUs = sysConfigService.getValue(Constant.CALL_CENTER_US);
        JSONObject jsonObject = JSONObject.parseObject(callCenterUs);
        return RestResponse.success().put("data",jsonObject);
    }

    @Resource
    private Producer producer;

    /**
     * 验证码
     *
     * @param response response
     * @param uuid     uuid
     */
    @GetMapping("captcha.jpg")
    public void captcha(HttpServletResponse response, String uuid) throws IOException {
        if (org.apache.commons.lang.StringUtils.isBlank(uuid)) {
            throw new BusinessException("uuid不能为空");
        }
        // 生成文字验证码
        String code = producer.createText();
        // 保存至redis有效期五分钟
        jedisUtil.set(KaptchaConfig.REDIS_KYE+uuid,code,KaptchaConfig.VALID_TIME);
        // 获取图片验证码
        BufferedImage image = producer.createImage(code);
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

}

